﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Utility
{
    public class IPHelper
    {

        #region 判断是否合法 IP

        /// <summary>
        /// 判断是否合法 IP
        /// </summary>
        /// <param name="strIP"></param>
        /// <returns></returns>
        public static bool ValidateIPAddress(string strIP)
        {
            if (null == strIP || "" == strIP.Trim() || Convert.IsDBNull(strIP))
                return false;

            return Regex.IsMatch(strIP, @"^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$");
        }

        #endregion

        #region 转换成数值

        /// <summary>
        ///  转换为数值
        /// </summary>
        /// <param name="IPAddr"></param>
        /// <returns></returns>
        public static long IP2Number(string IPAddr)
        {
            //字符串转换为数字
            System.Net.IPAddress ipaddress = System.Net.IPAddress.Parse(IPAddr);
            return ipaddress.Address;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dreamduip"></param>
        /// <returns></returns>
        public static string Number2IP(long dreamduip)
        {
            //数字转换为字符串
            System.Net.IPAddress ipaddress = System.Net.IPAddress.Parse(dreamduip.ToString());
            string[] array = ipaddress.ToString().Split('.');

            return string.Format("{0}.{1}.{2}.{3}", array[3], array[2], array[1], array[0]);

        }

        #endregion

        //#region 格式化

        ///// <summary>
        ///// 格式化
        ///// </summary>
        ///// <param name="IPAddr"></param>
        ///// <returns></returns>
        //public static string Format(string IPAddr)
        //{
        //    if (IPAddr[0] == '.')
        //        IPAddr = "0" + IPAddr;

        //    if (IPAddr[IPAddr.Length - 1] == '.')
        //        IPAddr += "0.0.0.";
        //    else
        //        IPAddr += ".0.0.0.";

        //    IPAddr = IPAddr.Substring(0, clsString.IndexOf(IPAddr, ".", 4));

        //    //   //去掉无用的0
        //    //   IPAddr = Regex.Replace(IPAddr,"^0{1,2}","");
        //    //   IPAddr = Regex.Replace(IPAddr,@"\.+0{1,2}",".");

        //    if (ValidateIPAddress(IPAddr))
        //        return IPAddr;

        //    return "0.0.0.0";
        //}

        //#endregion

        #region 比较两个IP的大小

        /// <summary>
        /// 比较两个IP的大小
        /// </summary>
        /// <param name="IP1"></param>
        /// <param name="IP2"></param>
        /// <returns></returns>
        public static int Compare(string IP1, string IP2)
        {
            if (!(ValidateIPAddress(IP1) && ValidateIPAddress(IP2)))
                throw new Exception("IP Address isn't Well Format!");

            long IPNum1 = IP2Number(IP1);
            long IPNum2 = IP2Number(IP2);

            if (IPNum1 == IPNum2)
                return 0;

            return IPNum1 > IPNum2 ? 1 : -1;
        }


        #endregion

        #region 判断一个IP是否包含在指定IP区间内

        /// <summary>
        /// 判断一个IP是否包含在指定IP区间内
        /// </summary>
        /// <param name="IPRegion"></param>
        /// <param name="IP"></param>
        /// <returns></returns>
        public static bool IsInclude(string[] IPRegion, string IP)
        {
            //验证
            if (null == IPRegion || null == IP || 0 == IPRegion.Length)
                return false;

            if (!ValidateIPAddress(IP))
                return false;

            if (1 == IPRegion.Length)
            {
                if (!ValidateIPAddress(IPRegion[0]))
                    return false;

                if (0 == Compare(IPRegion[0], IP))
                    return true;
            }

            if (!(ValidateIPAddress(IPRegion[0]) && ValidateIPAddress(IPRegion[1])))
                return false;

            long IPNum = IP2Number(IP);
            long IPNum1 = IP2Number(IPRegion[0]);
            long IPNum2 = IP2Number(IPRegion[1]);

            //比较
            if (Math.Min(IPNum1, IPNum2) <= IPNum && Math.Max(IPNum1, IPNum2) >= IPNum)
                return true;

            return false;
        }


        #endregion

        #region 判断两个IP区间是否重叠，重叠则返回合并区间，否则返回 NULL

        /// <summary>
        /// 判断两个IP区间是否重叠，重叠则返回合并区间，否则返回 NULL
        /// </summary>
        /// <param name="IPRegion1"></param>
        /// <param name="IPRegion2"></param>
        /// <returns></returns>
        public static string[] CheckOverlapAndMerge(string[] IPRegion1, string[] IPRegion2)
        {
            //验证
            if (null == IPRegion1 || null == IPRegion2 || 0 == IPRegion1.Length || 0 == IPRegion2.Length)
                return null;

            //分数组长度进行处理 =1 和 > 1
            if (1 == IPRegion1.Length)
            {
                if (!ValidateIPAddress(IPRegion1[0]))
                    throw new Exception("IP Address isn't Well Format!");

                if (1 == IPRegion2.Length)
                {
                    if (!ValidateIPAddress(IPRegion2[0]))
                        throw new Exception("IP Address isn't Well Format!");

                    //相等
                    if (Equals(IPRegion1[0], IPRegion2[0]))
                        return IPRegion1;
                }
                // > 1
                else
                {
                    if (!(ValidateIPAddress(IPRegion2[0]) && ValidateIPAddress(IPRegion2[1])))
                        throw new Exception("IP Address isn't Well Format!");

                    if (IsInclude(IPRegion2, IPRegion1[0]))
                        return IPRegion2;
                }
            }
            // >1
            else
            {
                if (!(ValidateIPAddress(IPRegion1[0]) && ValidateIPAddress(IPRegion1[1])))
                    throw new Exception("IP Address isn't Well Format!");

                if (1 == IPRegion2.Length)
                {
                    if (!ValidateIPAddress(IPRegion2[0]))
                        throw new Exception("IP Address isn't Well Format!");

                    if (IsInclude(IPRegion1, IPRegion2[0]))
                        return IPRegion1;
                }
                // > 1
                else
                {
                    if (!(ValidateIPAddress(IPRegion2[0]) && ValidateIPAddress(IPRegion2[1])))
                        throw new Exception("IP Address isn't Well Format!");

                    long IPNum1_1 = IP2Number(IPRegion1[0]);
                    long IPNum1_2 = IP2Number(IPRegion1[1]);
                    long IPNum2_1 = IP2Number(IPRegion2[0]);
                    long IPNum2_2 = IP2Number(IPRegion2[1]);

                    #region 大小格式整理 IP[0] <= IP[1]

                    if (IPNum1_1 > IPNum1_2)
                    {
                        string stemp = IPRegion1[0];
                        IPRegion1[0] = IPRegion1[1];
                        IPRegion1[1] = stemp;

                        long utemp = IPNum1_1;
                        IPNum1_1 = IPNum1_2;
                        IPNum1_2 = utemp;
                    }

                    if (IPNum2_1 > IPNum2_2)
                    {
                        string stemp = IPRegion2[0];
                        IPRegion2[0] = IPRegion2[1];
                        IPRegion2[1] = stemp;

                        long utemp = IPNum2_1;
                        IPNum2_1 = IPNum2_2;
                        IPNum2_2 = utemp;
                    }

                    #endregion

                    #region 判断合并

                    //互不包含
                    if (IPNum1_1 > IPNum2_2 || IPNum1_2 < IPNum2_1)
                        return null;

                    //合并
                    string[] result = new string[2];

                    result[0] = IPNum1_1 < IPNum2_1 ? IPRegion1[0] : IPRegion2[0];
                    result[1] = IPNum1_2 > IPNum2_2 ? IPRegion1[1] : IPRegion2[1];

                    return result;

                    #endregion
                }

            }

            return null;
        }


        #endregion

        #region 私有方法

        /// <summary>
        /// 移位转换_8
        /// </summary>
        /// <param name="bLow"></param>
        /// <param name="bHigh"></param>
        /// <returns></returns>
        private static ushort MAKEWORD(byte bLow, byte bHigh)
        {
            return ((ushort)(((byte)(bLow)) | ((ushort)((byte)(bHigh))) << 8));
        }

        /// <summary>
        /// 移位转换_16
        /// </summary>
        /// <param name="bLow"></param>
        /// <param name="bHigh"></param>
        /// <returns></returns>
        private static uint MAKELONG(ushort bLow, ushort bHigh)
        {
            return ((uint)(((ushort)(bLow)) | ((uint)((ushort)(bHigh))) << 16));
        }

        #endregion

        /// <summary>
        /// 返回当前客户IP
        /// </summary>
        /// <returns></returns>
        public static string GetClientIP()
        {
            return System.Web.HttpContext.Current.Request.ServerVariables.Get("Remote_Addr").ToString();
        }

        /// <summary>
        /// 将指定的IP，除指定长度外，按*显示
        /// </summary>
        /// <param name="ip">IP地址</param>
        /// <param name="length">显示长度</param>
        public static string IPRelace(string ip, int length)
        {
            string[] strArray = ip.Split(new char[] { '.' });
            if (strArray.Length != 4)
            {
                return "***.***.***.***";
            }
            return string.Format("{0}.{1}.***.***", strArray[0], strArray[1]);
        }

        /// <summary>
        /// 返回服务器MAC地址
        /// </summary>
        /// <returns></returns>
        public static string GetServerMAC()
        {
            System.Management.ManagementClass class1 = new System.Management.ManagementClass("Win32_NetworkAdapterConfiguration");
            System.Management.ManagementObjectCollection collection1 = class1.GetInstances();
            int num1 = 0;
            StringBuilder builder1 = new StringBuilder();
            using (System.Management.ManagementObjectCollection.ManagementObjectEnumerator enumerator1 = collection1.GetEnumerator())
            {
                while (enumerator1.MoveNext())
                {
                    System.Management.ManagementBaseObject obj1 = enumerator1.Current;
                    if ((bool)obj1.GetPropertyValue("IPEnabled"))
                    {
                        if (num1 > 0)
                        {
                            builder1.Append('|');
                        }
                        builder1.Append(obj1.GetPropertyValue("MacAddress").ToString());
                        num1++;
                    }
                    obj1.Dispose();
                }
            }
            return builder1.ToString().Replace(':', '-');
        }

        /// <summary>
        /// 返回服务器IP地址
        /// </summary>
        /// <returns></returns>
        public static string GetServerIP()
        {
            return System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList[0].ToString();
        }

        /// <summary>
        /// 返回服务器名称
        /// </summary>
        /// <returns></returns>
        public static string GetServerHostName()
        {
            return System.Net.Dns.GetHostName();
        }
    }
}
